package cc.co.cutenimy.nimyexplore.jdbc.driver.file;

import java.net.URL;
import java.sql.Driver;
import java.util.ArrayList;
import java.util.List;

import cc.co.cutenimy.nimyexplore.jdbc.driver.ClassPathLocation;
import cc.co.cutenimy.nimyexplore.jdbc.driver.DriverClassLoader;
import cc.co.cutenimy.nimyexplore.jdbc.driver.DriverDescription;
import cc.co.cutenimy.nimyexplore.jdbc.driver.DriverException;

public class FileDriverDescription implements DriverDescription {
	private final String driverClassName;
	private final ClassPathLocation[] pathLocations;

	public FileDriverDescription(String driverClass,
			ClassPathLocation[] pathLocations) {
		this.driverClassName = driverClass;
		this.pathLocations = pathLocations;
	}

	public String getDriverClass() {
		return driverClassName;
	}

	public boolean isValid() {
		if (driverClassName == null)
			return false;
		return true;
	}

	@SuppressWarnings("unchecked")
	protected Class<java.sql.Driver> loadClass(final String className)
			throws DriverException {
		// TODO How to manager the ClassLoader instances?
		try {
			return ((Class<Driver>) new DriverClassLoader(getUrls())
					.loadClass(className));
		} catch (ClassNotFoundException e) {
			throw new DriverException("Can't find class: " + className, e);
		}
	}

	private URL[] getUrls() throws DriverException {
		if (pathLocations == null) {
			return new URL[0];
		}
		List<URL> list = new ArrayList<URL>(pathLocations.length);
		for (ClassPathLocation location : pathLocations) {
			list.add(location.toURL());
		}
		return list.toArray(new URL[0]);
	}

	public Class<java.sql.Driver> loadDriverClass(String expected)
			throws DriverException {
		if (expected == null) {
			return loadClass(getDriverClass());
		} else {
			return loadClass(expected);
		}
	}

	public Class<java.sql.Driver> loadDriverClass() throws DriverException {
		return loadDriverClass(null);
	}
}
